package com.songlanyun.modules.rabbitmq.mq.consumer;

import com.rabbitmq.client.Channel;
import com.songlanyun.common.utils.DateUtil;
import com.songlanyun.modules.rabbitmq.MqConstant;
import com.songlanyun.modules.rabbitmq.entity.MsgLog;
import com.songlanyun.modules.rabbitmq.service.MsgLogService;
import com.songlanyun.modules.rabbitmq.service.SendMsgService;
import com.songlanyun.modules.rabbitmq.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;

import java.io.IOException;


@Slf4j
public abstract class BaseConsumer {

    private MsgLogService msgLogService;

    public  MsgLogService getMsgLogService() {
        if(msgLogService==null)
        {
            msgLogService = (MsgLogService) SpringContextUtil.getBean("msgLogService");
        }
        return msgLogService;
    }

    /**
     * 业务处理，需要自己去实现
     *
     * @param message
     */
    protected  abstract void process(Message message) throws IOException;

    public void handle(Message message, Channel channel) throws IOException {

        //1--- 取消息id
        String msgId = message.getMessageProperties().getMessageId();

        MessageProperties properties = message.getMessageProperties();
        long tag = properties.getDeliveryTag();
        if(!msgId.equals(SendMsgService.COMMON_MSG_MARK_CODE))
        {
            log.info("接收消息, msgId: {},时间：{}", msgId, DateUtil.getNowTime("yyyy-MM-DD HH:mm:ss"));
            //2---判断消息是否被消费，如果消费则不管
            MsgLog msgLog = getMsgLogService().selectByMsgId(msgId);

            //手动ack
            //channel.basicAck(tag, false);
            //重新放入队列
            //channel.basicNack(tag, false, true);
            //抛弃此条消息
            //channel.basicNack(tag, false, false);
            if (null == msgLog) {
                log.info("消息不存在, msgId: {}", msgId);
                channel.basicNack(tag, false, false);
                return;
            }
            if (msgLog.getStatus().equals(MqConstant.MsgLogStatus.CONSUMED_SUCCESS)) {// 消费幂等性
                channel.basicNack(tag, false, false);
                log.info("重复消费, msgId: {}", msgId);
                return;
            }
            try {
                process(message);
                getMsgLogService().updateStatus(msgId, MqConstant.MsgLogStatus.CONSUMED_SUCCESS);
                channel.basicAck(tag, false);
            } catch (Exception ex) {
                channel.basicNack(tag, false, false);
            }
        }
        else
        {
            try {
                process(message);
                channel.basicAck(tag, false);
            } catch (Exception ex) {
                channel.basicNack(tag, false, false);
            }
        }



    }

}
